﻿using FFTAI;
using FFTAI.Machine;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace S13Calibration
{
	public class CalibrationUI //: MonoBehaviour
	{
		private GameObject _mainUI;
		private Button _okBtn;
		private Button _noBtn;
		private Button _caliBtn;
		private Image _okImg;
		private Image _noImg;
		private Image _caliImg;
		private Text _msg;
		private Animation _pointer;
		private Animation _light;
		private Animator _rightHand;
		private Animator _leftHand;
		private Sprite _cali_s;
		private Sprite _cali_n;
		private Sprite _btn_no_s;
		private Sprite _btn_no_n;
		private Sprite _btn_yes_s;
		private Sprite _btn_yes_n;
		private SpriteState _btn_n_ss;
		private IniFile _localUIText;
		private S13Calibration _module;
		#region self
		private GameObject _calSelfObj;
		private Text _calSelfText;
		private Button _calSelfOKBtn;
		private Image _caliSelfImg;
		#endregion

		public void Load(S13Calibration module, object org)
		{
			this._module = module;

			_localUIText = IniMgr.LoadModuleLanguageFile(this._module.Name, "ui");
			_mainUI = GameObject.Instantiate(module.PrefabGet("CalibrateUI") as GameObject);
			_mainUI.transform.SetParent(LobbyUI.Ins.DefaultUI);
			_mainUI.transform.SetSiblingIndex(LobbyUI.Ins.DefaultUI.childCount - 3);
			_mainUI.transform.localPosition = Vector3.zero;
			_mainUI.transform.localScale = Vector3.one;
			MB.DontDestroyOnLoad(_mainUI);

			#region Calibrate组件变量赋值
			_okBtn = _mainUI.transform.Find("Calibrate/Btn/OK").GetComponent<Button>();
			_okBtn.gameObject.SetActive(false);

			_noBtn = _mainUI.transform.Find("Calibrate/Btn/NO").GetComponent<Button>();
			_noBtn.gameObject.SetActive(false);

			_caliBtn = _mainUI.transform.Find("Calibrate/Btn/Calibrate").GetComponent<Button>();
			_caliBtn.gameObject.SetActive(false);

			_okImg = _okBtn.gameObject.transform.Find("Image").GetComponent<Image>();
			_noImg = _noBtn.gameObject.transform.Find("Image").GetComponent<Image>();
			_caliImg = _caliBtn.gameObject.transform.Find("Image").GetComponent<Image>();

			_msg = _mainUI.transform.Find("Calibrate/Msg").GetComponent<Text>();
			_pointer = _mainUI.transform.Find("Calibrate/Bg/Pointer").GetComponent<Animation>();
			_light = _mainUI.transform.Find("Calibrate/Bg/Light").GetComponent<Animation>();

			_rightHand = _mainUI.transform.Find("Calibrate/Bg/RightHand").GetComponent<Animator>();
			_leftHand = _mainUI.transform.Find("Calibrate/Bg/LeftHand").GetComponent<Animator>();
			#endregion

			this.OnEnable();
		}

		private string GetLocalText(string key)
		{
			string text = key;
			if (_localUIText != null)
			{
				text = _localUIText.GetValue(key);
			}
			return text;
		}

		void OnEnable()
		{
			Sprite[] a = ResourceLoader.Ins.SpritesGet(LobbyUI.SharedModule, $"images/DefaultUI{ThemeMgr.ThemeSplitMarker}.png");// this._module.PlatformSpritesGet("images/DefaultUIfftai2015.png");
			Sprite btn_s = Array.Find<Sprite>(a, (s) => s.name == "common_btn_new_s");

			_btn_n_ss = new SpriteState
			{
				highlightedSprite = btn_s,
				pressedSprite = btn_s
			};

			_cali_s = Array.Find<Sprite>(a, (s) => s.name == "calibration_s");
			_cali_n = Array.Find<Sprite>(a, (s) => s.name == "calibration_n");
			_btn_no_s = Array.Find<Sprite>(a, (s) => s.name == "common_btn_no_s");
			_btn_no_n = Array.Find<Sprite>(a, (s) => s.name == "common_btn_no_n");
			_btn_yes_s = Array.Find<Sprite>(a, (s) => s.name == "common_btn_yes_s");
			_btn_yes_n = Array.Find<Sprite>(a, (s) => s.name == "common_btn_yes_n");

			_okBtn.onClick.AddListener(ClosedUI);
			_noBtn.onClick.AddListener(OnNoBtnClick);
			_caliBtn.onClick.AddListener(Calibrate);

			_okBtn.spriteState = _btn_n_ss;
			_noBtn.spriteState = _btn_n_ss;
			_caliBtn.spriteState = _btn_n_ss;

			_caliImg.sprite = _cali_n;
			_okImg.sprite = _btn_yes_n;
			_noImg.sprite = _btn_no_n;

			AddEventTriggerEvent(_okBtn, EventTriggerType.PointerEnter, HightLightBtn);
			AddEventTriggerEvent(_okBtn, EventTriggerType.PointerExit, HightCloseBtn);
			AddEventTriggerEvent(_noBtn, EventTriggerType.PointerEnter, HightLightBtn);
			AddEventTriggerEvent(_noBtn, EventTriggerType.PointerExit, HightCloseBtn);
			AddEventTriggerEvent(_caliBtn, EventTriggerType.PointerEnter, HightLightBtn);
			AddEventTriggerEvent(_caliBtn, EventTriggerType.PointerExit, HightCloseBtn);
			Calibrate();
		}

		private void Calibrate()
		{	
			FFTAI.MB.Ins.StartCoroutine(CaliEffect(CaliResult.Caling));

			_caliImg.sprite = _cali_n;
			_okBtn.gameObject.SetActive(false);
			_noBtn.gameObject.SetActive(false);
			_caliBtn.gameObject.SetActive(false);

			OriginCalibrate();
		}

		private void ClosedUI()
		{
			this._module.Unload();
		}

		private void OnNoBtnClick()
		{
			ClosedUI();
		}

		#region Origin
		private void OriginCalibrate()
		{
			_msg.text = GetLocalText("Caling");
			if (RobotMgr.Ins.Robot.IsFault != null)
			{
				RobotMgr.Ins.Robot.ResetFault();
			}
			FFTAI.MB.Ins.StartCoroutine(Origin());
		}

		private IEnumerator Origin()
		{
			float timeOut = 0;

			FFTAI.MB.Ins.StartCoroutine(CaliEffect(CaliResult.Caling));
			while (RobotMgr.Ins.ConnSucceed)
			{
				timeOut += 2;

				if (timeOut >= 5 && RobotMgr.Ins.Robot.IsCalibrated)
				{
					break;
				}

				if (timeOut > 30)
				{
					break;
				}

				yield return new WaitForSeconds(2f);
			}

			if (!RobotMgr.Ins.Robot.IsCalibrated)
			{
				CalibratedFaild();
				yield break;
			}

			CalibratedSuccess();
	
			yield return new WaitForSeconds(2f);
			RobotMgr.Ins.Robot.Call("StartTrain", null);
			yield return new WaitForSeconds(1f);
			RobotMgr.Ins.Robot.Call("SendMessageStartPosition", 0);
			ClosedUI();
		}
		#endregion

		private void CalibratedSuccess()
		{
			FFTAI.MB.Ins.StartCoroutine(CaliEffect(CaliResult.Success));
			_msg.text = GetLocalText("CalSuccess");
			var settings = new Dictionary<string, string>
			{
				{ "CalibrationStatus",Constants.Success },
			};
			settings.Add("OriginStatus", Constants.Success);
			DatabaseMgr.Ins.MachineBLL.SetSettings(settings);
		}

		private void CalibratedFaild()
		{
			FFTAI.MB.Ins.StartCoroutine(CaliEffect(CaliResult.Fail));
			_msg.text = GetLocalText("CalFail");
			_noBtn.gameObject.SetActive(true);
			_caliBtn.gameObject.SetActive(true);
			var settings = new Dictionary<string, string>
			{
				{ "CalibrationStatus",Constants.Fail },
			};
			settings.Add("OriginStatus", Constants.Fail);
			DatabaseMgr.Ins.MachineBLL.SetSettings(settings);
		}

		private IEnumerator CaliEffect(CaliResult cr)
		{
			switch (cr)
			{
				case CaliResult.Success:
					_rightHand.speed = 0;
					_leftHand.speed = 0;
					_pointer.Play("Pointer2");
					_light.Play("Light2");

					yield return new WaitUntil(() =>
					{
						if (_pointer != null)
						{
							return 1 - _pointer["Pointer2"].normalizedTime <= 0.02;
						}

						return false;
					}
					);
					_pointer.Stop("Pointer2");
					_light.enabled = false;

					yield break;
				case CaliResult.Fail:
					_rightHand.speed = 0;
					_leftHand.speed = 0;
					_pointer.Play("Pointer2");
					_light.Play("Light3");
					yield return new WaitUntil(() =>
					{
						if (_pointer != null)
						{
							return 1 - _pointer["Pointer2"].normalizedTime <= 0.02;
						}
						return false;
					});
					_pointer.Stop("Pointer2");
					_light.enabled = false;
					break;
				case CaliResult.Caling:
					_light.enabled = true;
					_rightHand.speed = 1;
					_leftHand.speed = 1;
					_pointer.Play("Pointer1");
					_light.Play("Light1");
					break;
				default:
					break;
			}
		}

		public void Unload()
		{
			if (_mainUI != null)
			{
				FFTAI.MB.Ins.StopCoroutine("CaliEffect");

				if (_light != null) _light.Stop();
				if (_pointer != null) _pointer.Stop();
				GameObject.Destroy(_mainUI);

				_mainUI = null;
				_light = null;
				_pointer = null;
			}
		}

		#region 按钮移入移出高亮事件
		public void OnPointerEnter(string BtnName)
		{
			switch (BtnName)
			{
				case "Calibrate":
					_caliImg.sprite = _cali_s;
					break;
				case "OK":
					_okImg.sprite = _btn_yes_s;
					break;
				case "NO":
					_noImg.sprite = _btn_no_s;
					break;
				case "CalSelfOK":
					_caliSelfImg.sprite = _btn_yes_s;
					break;
				default:
					break;
			}
		}

		public void OnPointerExit(string BtnName)
		{
			switch (BtnName)
			{
				case "Calibrate":
					_caliImg.sprite = _cali_n;
					break;
				case "OK":
					_okImg.sprite = _btn_yes_n;
					break;
				case "NO":
					_noImg.sprite = _btn_no_n;
					break;
				case "CalSelfOK":
					_caliSelfImg.sprite = _btn_yes_n;
					break;
				default:
					break;
			}
		}

		private void HightLightBtn(BaseEventData arg0)
		{
			PointerEventData point = arg0 as PointerEventData;
			if (point.pointerEnter.gameObject != null)
			{
				OnPointerEnter(point.pointerEnter.gameObject.name);
			}
		}

		private void HightCloseBtn(BaseEventData arg0)
		{
			PointerEventData point = arg0 as PointerEventData;
			if (point.pointerEnter.gameObject != null)
			{
				OnPointerExit(point.pointerEnter.gameObject.name);
			}
		}

		private void AddEventTriggerEvent(Component obj, EventTriggerType eventTriggerType, UnityAction<BaseEventData> callback)
		{
			EventTrigger.Entry entry = null;
			EventTrigger trigger = obj.GetComponent<EventTrigger>();

			if (trigger != null) // 已有EventTrigger
			{
				// 查找是否已经存在要注册的事件
				foreach (EventTrigger.Entry existingEntry in trigger.triggers)
				{
					if (existingEntry.eventID == eventTriggerType)
					{
						entry = existingEntry;
						break;
					}
				}
			}
			else
			{
				trigger = obj.gameObject.AddComponent<EventTrigger>();
			}
			// 如果这个事件不存在，就创建新的实例
			if (entry == null)
			{
				entry = new EventTrigger.Entry();
				entry.eventID = eventTriggerType;
				entry.callback = new EventTrigger.TriggerEvent();
			}
			entry.callback.AddListener(callback);
			trigger.triggers.Add(entry);
		}
		#endregion
	}
}